#include "stdafx.h"
#include "FileBase.h"
#include "DateTime.h"
#include <io.h>
#include <stdlib.h>

using namespace std;

FileBase::FileBase(string p_strFilePath, const unsigned int p_uiBufferSize)
	:m_strFilePath(p_strFilePath)
	,m_pszBuffer(NULL)
	,m_cFileStream()
	,m_uiFileLength(0)
{
	m_pszBuffer = (char*)malloc(p_uiBufferSize);
	m_uiBufferSize = p_uiBufferSize;
	if(NULL == m_pszBuffer)
	{
		LOG(ERROR) << "Cannot initialize buffer of file";
	}
}

FileBase::~FileBase()
{
	RELEASE(m_pszBuffer)
}

bool FileBase::OpenFile()
{
	// Verify if file is exist
	if(false == IsFileExist())
	{
		LOG(ERROR) << m_strFilePath << " does not exist";
		return false;
	}

	memset(m_pszBuffer,0,m_uiBufferSize);
	// Open file
	try
	{
		m_cFileStream.open(m_strFilePath.c_str(),ios::binary);
	}
	catch (ifstream::failure e)
	{
		LOG(ERROR) << m_strFilePath << " cannot be opened";
		return false;
	}

	// Get length of the file
	m_cFileStream.seekg(0,ios::end);
	m_uiFileLength = m_cFileStream.tellg();

	// [TODO] If file length greater than configured then return false
	// Need to check the length of dbf file. If length greater than configured, memory need to be re-allocate
	if(m_uiFileLength > m_uiBufferSize)
	{
		if (NULL != m_pszBuffer)
		{
			free(m_pszBuffer);
			m_pszBuffer = NULL;
		}
		
		m_pszBuffer = (char*)malloc(m_uiFileLength + 1);
		m_uiBufferSize = m_uiFileLength + 1;
		LOG(WARNING) << "Extend memory for " << m_strFilePath << ". New memory size : " << m_uiBufferSize;
	}

	m_cFileStream.seekg(0,ios::beg);
	m_cFileStream.read(m_pszBuffer,m_uiFileLength + 1);
	//if (NULL == m_cFileStream)
	//{
	//	LOG(ERROR) << "Read file error" << endl;
	//	return false;
	//}

	return true;
}

bool FileBase::CloseFile()
{
	m_cFileStream.close();
	//m_uiFileLength = 0;
	return true;
}

bool FileBase::IsFileExist()
{
	int iRet = _access(m_strFilePath.c_str(),0);
	if(-1 == iRet)
	{
		return false;
	}
	else
	{
		return true;
	}
}

void FileBase::GetDBFTime(Time& p_stTime, int p_iType)
{
	DbfHeadNew* pstDBFHead = (DbfHeadNew*)m_pszBuffer;
	FieldElement* pstField = (FieldElement*)(m_pszBuffer + sizeof(DbfHeadNew));

	switch(p_iType)
	{
	case FILETYPE_SHOW:
		memcpy(p_stTime.szTime,(char*)(m_pszBuffer + pstDBFHead->m_usHeadLength + pstField[1].m_ulOffset),pstField[1].m_cFieldLength);
		break;
	case FILETYPE_SJSXX:
		memcpy(p_stTime.szTime,(char*)(m_pszBuffer + pstDBFHead->m_usHeadLength + pstField[17].m_ulOffset),pstField[17].m_cFieldLength);
		break;
	case FILETYPE_SJSHQ:
		memcpy(p_stTime.szTime,(char*)(m_pszBuffer + pstDBFHead->m_usHeadLength + pstField[7].m_ulOffset),pstField[7].m_cFieldLength);
		break;
	default:
		break;
	}
}

void FileBase::GetDBFDate(Time& p_stTime, int p_iType)
{
	DbfHeadNew* pstDBFHead = (DbfHeadNew*)m_pszBuffer;
	FieldElement* pstField = (FieldElement*)(m_pszBuffer + sizeof(DbfHeadNew));

	switch(p_iType)
	{
	case FILETYPE_SHOW:
		memcpy(p_stTime.szTime,(char*)(m_pszBuffer + pstDBFHead->m_usHeadLength + pstField[5].m_ulOffset),pstField[5].m_cFieldLength);
		break;
	case FILETYPE_STBHQ:
	case FILETYPE_GZLX:
	case FILETYPE_SJSXX:
	case FILETYPE_SJSHQ:
	case FILETYPE_HGHQ:
	case FILETYPE_HGXXN:
		memcpy(p_stTime.szTime,(char*)(m_pszBuffer + pstDBFHead->m_usHeadLength + pstField[1].m_ulOffset),pstField[1].m_cFieldLength);
		break;
	default:
		break;
	}
}

void FileBase::SetFileFullPath(string p_strFilePath)
{
	m_strFilePath = p_strFilePath;
}

string FileBase::GetFileDir()
{
	return m_strFilePath.substr(0,m_strFilePath.find_last_of("\\") + 1);
}

bool FileBase::Process()
{
	return true;
}